package com.mrd.spring.filter;

import com.mrd.framework.security.config.SecurityConstants;
import com.mrd.framework.utils.HttpUtils;
import com.mrd.framework.utils.SpringUtils;
import com.mrd.gtimp.business.entity.UserService;
import com.mrd.gtimp.business.repository.UserServiceDao;
import com.mrd.gtimpframe.entity.User;
import com.mrd.gtimpframe.repository.CompanyMapper;
import com.mrd.gtimpframe.repository.UserMapper;
import com.mrd.util.StringUtils;
import com.mrd.util.WeiChatUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Arrays;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.transaction.Transactional;

/**
 * Created by dengdc on 2017/7/15.
 */
public class WeChatFilter implements Filter {

  private static Logger logger = LoggerFactory.getLogger(WeChatFilter.class);

  @Override
  @Transactional
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    String rqUri = ((HttpServletRequest) request).getRequestURI();
    System.out.println(rqUri);
    printRequest();
    HttpSession httpSession = HttpUtils.getSession();
    Object sessionUser = httpSession.getAttribute(SecurityConstants.NEW_SESSION_USER_NAME);
    String openid;
    String dynamicCode = request.getParameter("code");
    HttpServletResponse httpServletResponse = (HttpServletResponse) response;
    if (rqUri.contains("/wx/brokedown")) {
      chain.doFilter(request, response);
      return;
    }

    boolean needValidUser = true;
    if (rqUri.contains("/wx/bind") || rqUri.contains("/wx/news")
        || rqUri.contains("/wx/newShow")) {
      // 绑定页面不要求已经做过模拟登录
      needValidUser = false;
    }
    if (StringUtils.isEmpty(dynamicCode)) {
      // 需要进一步验证 是否已经模拟登录
      if (sessionUser == null && needValidUser) {
        System.out.println("no code and not monitor login");
        // 没有进行模拟登录，说明请求有问题，返回错误页面
        httpServletResponse.sendRedirect("brokedown.html");
      }
    } else {
      // 为了避免用户多次绑定、用户切换后造成数据隔离失效。所以传入code就必须检查对应的用户。
      // 调用微信接口查询openid，接着获取用户信息存入session，模拟登录
      openid = WeiChatUtil.getOpenidFromWeChatServer(dynamicCode);
      System.out.println("to WeChat Service get openid :" + openid);
      Object sessionOpenid = httpSession.getAttribute(SecurityConstants.WE_CHAT_OPEN_ID);
      if (sessionOpenid != null) {
        openid = sessionOpenid.toString();
        System.out.println("get openid from session :" + openid);
      }
      System.out.println(2);

      // 通过接口获取不到,有两种情况，1 网络问题 2、这个code已经被使用过了
//      openid = "oqNcwwENemIqOucIopl1jAh9psM8"; //测试用
      if (StringUtils.isEmpty(openid)) {
        if (sessionUser == null) { // 没有登录，去往错误页面
          httpServletResponse.sendRedirect("brokedown.html");
          System.out.println(3);
          return;
        }
        // 不更新登录用户，进入下一个过滤器
        chain.doFilter(request, response);
        return; // 退出此过滤器,不在往下
      }
      httpSession.setAttribute(SecurityConstants.WE_CHAT_OPEN_ID, openid);
      if (needValidUser) {
        // 能查到openid，就要检查openid对应的绑定用户
        UserServiceDao userServiceDao = SpringUtils.getBean(UserServiceDao.class);
        UserService userService = userServiceDao.findByDeviceCodeAndStatus(openid, "1");
        if (userService == null) {
          // 没有绑定微信账号，前往绑定页面
          httpServletResponse.sendRedirect("bind.html");
          return;// 退出此过滤器,不在往下
        }
        // 查询用户信息，模拟登录
        try {
          User user = SpringUtils.getBean(UserMapper.class)
              .selectByPrimaryKey(userService.getUserId());
          user.setCompany(SpringUtils.getBean(CompanyMapper.class)
                              .selectByUserId(user.getuId()));
          httpSession.setAttribute(SecurityConstants.NEW_SESSION_USER_NAME, user);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
    chain.doFilter(request, response);
    System.out.println("sessionId : " + httpSession.getId());
  }

  private void printRequest() {
    HttpServletRequest request = HttpUtils.getRequest();
    Map<String, String[]> parameterMap = request.getParameterMap();
    if (parameterMap != null) {
      for (String key : parameterMap.keySet()) {
        System.out.println("request parameter key[" + key + "] values["
                           + Arrays.toString(parameterMap.get(key)) + "]");
      }
    }
    // Enumeration<String> attributeNames = request.getAttributeNames();
    // if(attributeNames != null){
    // while (attributeNames.hasMoreElements()){
    // String attrName = attributeNames.nextElement();
    // System.out.println("request attribute attrName["+attrName+"] value["+
    // request.getAttribute(attrName)+"]");
    // }
    // }
  }

  public String buildUri(String uri) {
    HttpServletRequest request = HttpUtils.getRequest();
    Map<String, String[]> parameterMap = request.getParameterMap();
    StringBuilder sb = new StringBuilder(uri).append("?");
    if (parameterMap != null) {
      for (String key : parameterMap.keySet()) {
        sb.append(key).append("=")
            .append(Arrays.toString(parameterMap.get(key)).replaceAll("(\\[])", ""))
            .append("&");
      }
    }
    if (sb.length() > (uri.length() + 1)) {
      sb.deleteCharAt(sb.length() - 1);
    }
    System.out.println(uri + "?" + sb.toString());
    return uri + "?" + sb.toString();
  }

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    System.err.println("WeChatFilter init");
  }

  @Override
  public void destroy() {
    System.err.println("WeChatFilter destroy");
  }
}
